﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Security.Cryptography;
using System.IO;
using System.Globalization;

namespace Synchros
{
    /// <summary>
    /// 加解密的类
    /// </summary>
    public class Cryptogram
    {
        
        /// <summary>
        /// 普通加密
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public static string Encrypt(string input)
        {
            string output = string.Empty;
            try
            {
                //普通加密算法
                output = Cryptogram.AESEncrypt(input, "fkasdjflasdjklfjasdksjdf", "ad&*as&*SSFa1512");
            }
            catch (Exception ex)
            {
                throw ex;
            }
            return output;
        }

        /// <summary>
        /// 普通解密
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public static string Decrypt(string input)
        {
            string output = string.Empty;
            try
            {
                //普通解密算法
                output = Cryptogram.AESDecrypt(input, "fkasdjflasdjklfjasdksjdf", "ad&*as&*SSFa1512");
            }
            catch (Exception ex)
            {
                throw ex;
            }

            return output;
        }


        /// <summary>
        /// AES加密
        /// </summary>
        /// <param name="str">要加密的明文</param>
        /// <param name="key">密钥（转成UTF-8码后的长度必须为16，24或者32）</param>
        /// <param name="vector">初始化向量（转成UTF-8码后的长度必须为16）</param>
        /// <returns></returns>
        private static string AESEncrypt(string str, string key, string vector)
        {
            Byte[] bKey = Encoding.UTF8.GetBytes(key);
            Byte[] bVector = Encoding.UTF8.GetBytes(vector);
            if (!(bKey.Length == 16 || bKey.Length == 24 || bKey.Length == 32))
            {
                throw new Exception("AES加密出错:密钥字符串长度必须为16，24或者32");
            }
            if (bVector.Length != 16)
            {
                throw new Exception("AES加密出错:初始化向量字符串长度必须为16");
            }

            Byte[] Cryptograph = null; // 加密后的密文
            Rijndael Aes = Rijndael.Create();
            byte[] data = Encoding.UTF8.GetBytes(str);
            try
            {
                // 开辟一块内存流
                using (MemoryStream Memory = new MemoryStream())
                {
                    // 把内存流对象包装成加密流对象
                    using (CryptoStream Encryptor = new CryptoStream(Memory, Aes.CreateEncryptor(bKey, bVector), CryptoStreamMode.Write))
                    {
                        // 明文数据写入加密流
                        Encryptor.Write(data, 0, data.Length);
                        Encryptor.FlushFinalBlock();
                        Cryptograph = Memory.ToArray();
                    }
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
            return BitConverter.ToString(Cryptograph).Replace("-", ""); ;
        }

        /// <summary>
        /// AES解密
        /// </summary>
        /// <param name="str">要解密的明文</param>
        /// <param name="key">密钥（转成UTF-8码后的长度必须为16，24或者32）</param>
        /// <param name="vector">初始化向量（转成UTF-8码后的长度必须为16）</param>
        private static string AESDecrypt(string str, string key, string vector)
        {
            Byte[] bKey = Encoding.UTF8.GetBytes(key);
            Byte[] bVector = Encoding.UTF8.GetBytes(vector);
            if (!(bKey.Length == 16 || bKey.Length == 24 || bKey.Length == 32))
            {
                throw new Exception("AES解密出错:密钥字符串长度必须为16，24或者32");
            }
            if (bVector.Length != 16)
            {
                throw new Exception("AES解密出错:初始化向量字符串长度必须为16");
            }

            Byte[] Original = null; // 解密后的明文

            Rijndael Aes = Rijndael.Create();
            byte[] data = new byte[str.Length / 2];
            try
            {
                for (int i = 0; i < str.Length; i += 2)
                {
                    data[i / 2] = byte.Parse(str.Substring(i, 2), NumberStyles.HexNumber);
                }
                // 开辟一块内存流，存储密文
                using (MemoryStream Memory = new MemoryStream(data))
                {
                    // 把内存流对象包装成加密流对象
                    using (CryptoStream Decryptor = new CryptoStream(Memory,
                    Aes.CreateDecryptor(bKey, bVector), CryptoStreamMode.Read))
                    {
                        // 明文存储区
                        using (MemoryStream OriginalMemory = new MemoryStream())
                        {
                            Byte[] Buffer = new Byte[1024];
                            Int32 readBytes = 0;
                            while ((readBytes = Decryptor.Read(Buffer, 0, Buffer.Length)) > 0)
                            {
                                OriginalMemory.Write(Buffer, 0, readBytes);
                            }

                            Original = OriginalMemory.ToArray();
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }

            return Encoding.UTF8.GetString(Original);
        }
    }
}